package com.lh.schedule;

import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.lh.entity.table.*;
import com.lh.mapper.*;
import com.lh.utils.LogUtil;
import com.lh.utils.SmsGetSenderWithConfigUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;

import cn.hutool.core.date.DateUtil;

@Component
public class UpdateDeadlineNodeInfoSchedule {

	private LogUtil LOG = new LogUtil(UpdateDeadlineNodeInfoSchedule.class);

    @Resource
    private ReminderInfoMapper reminderInfoMapper;
    @Resource
    private TicketProblemInfoMapper ticketProblemInfoMapper;
    @Value("${schedule.updateDeadlineNodeInfo.warningDayTime:5}")
    @Resource
    private DeadlineNodeMapper deadlineNodeMapper;

    @Resource
    private DeadlineRectificationPeriodMapper deadlineRectificationPeriodMapper;
    @Resource
    private ReminderPersonMapper reminderPersonMapper;

    @Resource
    private RectificationInfoMapper rectificationInfoMapper;

    @Resource
    private ChangeWarnLevelMapper changeWarnLevelMapper;



    @Scheduled(cron = "${schedule.updateDeadlineNodeInfo.scheduleCron:-}")
    public void processDeadlineNodes() {
        // 1. 查询数据
        List<DeadlineNode> deadlineNodeList = deadlineNodeMapper.selectList(null); // 后续优化：加条件+分页

        List<DeadlineRectificationPeriod> deadlineRectificationPeriods = deadlineRectificationPeriodMapper.selectList(
                new LambdaQueryWrapper<DeadlineRectificationPeriod>()
                        .eq(DeadlineRectificationPeriod::getIsApproval, 1)
        );
        // 2. 建立：DeadlineNode的id → 对应的对应的所有DeadlineRectificationPeriod 的映射（分组）
        // 关键：确认 DeadlineRectificationPeriod 中关联 DeadlineNode 的字段（此处假设为 nodeId，需按实际表结构修改！）
        Map<Integer, List<DeadlineRectificationPeriod>> nodeIdToPeriodsMap = deadlineRectificationPeriods.stream()
                .filter(period -> period.getDeadlineNodeId() != null) // 过滤无关联的无效数据
                .collect(Collectors.groupingBy(DeadlineRectificationPeriod::getDeadlineNodeId));

        Date now = new Date();

        // 3. 遍历每个DeadlineNode，处理时间替换和状态计算
        for (DeadlineNode node : deadlineNodeList) {
            Integer nodeId = node.getId();
            Date effectiveDeadline = node.getDeadline(); // 初始为原deadline

            // 3.1 若当前node有对应的整改周期记录，取最新的rectificationTime替换effectiveDeadline
            if (nodeIdToPeriodsMap.containsKey(nodeId)) {
                List<DeadlineRectificationPeriod> periods = nodeIdToPeriodsMap.get(nodeId);
                if (CollectionUtils.isNotEmpty(periods)) {
                    // 按rectificationTime降序排序，取第一个（时间最新）的整改时间
                    DeadlineRectificationPeriod latestPeriod = periods.stream()
                            .filter(period -> period.getRectificationTime() != null) // 过滤无时间的无效记录
                            .max(Comparator.comparing(DeadlineRectificationPeriod::getRectificationTime)) // 降序取最大
                            .orElse(null);
                    // 若存在最新整改时间，替换effectiveDeadline
                    if (latestPeriod != null) {
                        effectiveDeadline = latestPeriod.getRectificationTime();
                        // （可选）若需持久化更新node的deadline字段到数据库，可在此处设置
                        // node.setDeadline(effectiveDeadline);
                    }
                }
            }
            // 3.2 原状态计算逻辑（将原 node.getDeadline() 替换为 effectiveDeadline）
            Integer status = 0; // 0蓝色，1黄色，2红色
            if (node.getEndTime() != null && effectiveDeadline != null) {
                // 有结束时间且有有效截止时间：结束时间超有效截止时间 → 红色
                if (node.getEndTime().after(effectiveDeadline)) {
                    status = 2;
                }
            } else {
                // 非已完成（无结束时间）：判断有效截止时间与当前时间的关系
                if (effectiveDeadline != null) {
                    if (effectiveDeadline.before(now)) {
                        // 超期 → 红色
                        status = 2;
                    } else if (effectiveDeadline.before(DateUtil.offsetDay(now, 5))) {
                        // 5天内到期 → 黄色
                        status = 1;
                    }
                    // 否则（5天以上）→ 蓝色（默认0）
                }
            }

            // 3.3 原进度判断和warnLevel更新逻辑（保持不变）
            if (node.getProgress() != null && node.getProgress().equals("/")) {
                // 进度为"/"时不处理
            } else {
                DeadlineNode updateNode = new DeadlineNode();
                updateNode.setId(nodeId);

                // 数据变化时才更新（避免无效SQL）
                String newWarnLevel = String.valueOf(status);
                if (node.getWarnLevel() == null || !node.getWarnLevel().equals(newWarnLevel)) {
                    System.out.println("newWarnLevel : "+newWarnLevel);
                    updateNode.setWarnLevel(newWarnLevel);
                    deadlineNodeMapper.updateWithNullById(updateNode); // 假设该方法支持更新非null字段
//                    node.setWarnLevel(newWarnLevel); // 同步内存中对象的状态
//                    sendRemind(node); // 发送提醒
                }
                // 冗余赋值，可删除（上方已处理更新）
                // updateNode.setWarnLevel(newWarnLevel);
            }
        }

        // 更新记录
        saveWarnLevelChange();
    }


    public void saveWarnLevelChange(){

        List<RectificationInfo> rectificationInfoList = fetchAllRectification("");

        List<DeadlineRectificationPeriod> finalDeadlinePeriods =
                deadlineRectificationPeriodMapper.selectList(new LambdaQueryWrapper<DeadlineRectificationPeriod>()
                        .eq(DeadlineRectificationPeriod::getIsApproval,1).orderByDesc(DeadlineRectificationPeriod::getId));

        List<Integer> allIds = rectificationInfoList.stream()
                .map(RectificationInfo::getId)
                .collect(Collectors.toList());

        final Map<Integer, List<DeadlineNode>> finalNodeMap;

        if (CollectionUtil.isNotEmpty(allIds)) {
            List<DeadlineNode> allNodes = deadlineNodeMapper.selectList(
                    new LambdaQueryWrapper<DeadlineNode>()
                            .in(DeadlineNode::getRectificationId, allIds)
                            .orderByDesc(DeadlineNode::getId)
            );
            finalNodeMap = allNodes.stream()
                    .collect(Collectors.groupingBy(DeadlineNode::getRectificationId));
        } else {
            finalNodeMap = Collections.emptyMap();
        }
        List<ChangeWarnLevel> changeWarnLevels= new ArrayList<>();
        if (CollectionUtil.isNotEmpty(rectificationInfoList)) {
            List<RectificationInfo> processedList = new ArrayList<>(rectificationInfoList.size());
            // 用于记录需要更新的对象（仅包含有变化的）
            List<RectificationInfo> needUpdateList = new ArrayList<>();

            for (RectificationInfo rectificationInfo1 : rectificationInfoList) {
                // 1. 记录修改前的关键字段（根据实际业务需要补充其他可能变化的字段）
                Integer oldWarnLevel = rectificationInfo1.getWarnLevel();
                String oldCurrentNode = rectificationInfo1.getCurrentNode();

                // 2. 处理逻辑（原逻辑不变）
                List<DeadlineNode> deadlineNodeList = finalNodeMap.getOrDefault(rectificationInfo1.getId(), new ArrayList<>());
                deadlineNodeList = filiterNode(rectificationInfo1, deadlineNodeList); // 注意拼写：建议改为filterNode
                RectificationInfo updatedInfo = calcWarnLevel(rectificationInfo1, deadlineNodeList, finalDeadlinePeriods);

                Integer newLevel = updatedInfo.getWarnLevel();
                if (!Objects.equals(oldWarnLevel, newLevel)) {
                    ChangeWarnLevel changeWarnLevel = new ChangeWarnLevel();
                    changeWarnLevel.setRectificationId(rectificationInfo1.getId());
                    changeWarnLevel.setOldWarnLevel(oldWarnLevel);
                    changeWarnLevel.setNewWarnLevel(newLevel);
                    changeWarnLevel.setCurrentNode(updatedInfo.getCurrentNode());
                    changeWarnLevel.setCreatTime(new Date()); // 注意拼写：建议改为createTime
                    changeWarnLevels.add(changeWarnLevel);
                }

                // 3. 更新原始对象
                rectificationInfo1.setWarnLevel(newLevel);
                rectificationInfo1.setCurrentNode(updatedInfo.getCurrentNode());
                processedList.add(rectificationInfo1);
                // 4. 对比修改前后的字段，判断是否需要更新（根据实际业务补充其他字段）
                boolean hasChanged = !Objects.equals(oldWarnLevel, newLevel)
                        || !Objects.equals(oldCurrentNode, updatedInfo.getCurrentNode());
                if (hasChanged) {
                    needUpdateList.add(rectificationInfo1);
                }
            }
//            rectificationInfoList = processedList;
            // 5. 仅更新有变化的对象
            for (RectificationInfo info : needUpdateList) {
                rectificationInfoMapper.updateById(info);
            }
        } else {
            // 如果列表为空，无需更新
        }
        // 插入变更记录的逻辑不变
        for (ChangeWarnLevel changeWarnLevel : changeWarnLevels) {
            changeWarnLevelMapper.insert(changeWarnLevel);
        }
//        if (CollectionUtil.isNotEmpty(rectificationInfoList)) {
//            List<RectificationInfo> processedList = new ArrayList<>(rectificationInfoList.size());
//            for (RectificationInfo rectificationInfo1 : rectificationInfoList) {
//                // 获取并过滤节点列表
//                List<DeadlineNode> deadlineNodeList = finalNodeMap.getOrDefault(rectificationInfo1.getId(), new ArrayList<>());
//                deadlineNodeList = filiterNode(rectificationInfo1, deadlineNodeList); // 注意：方法名可能存在拼写错误(filterNode)
//                Integer oldLevel = rectificationInfo1.getWarnLevel();
//                // 计算警告级别
//                RectificationInfo updatedInfo = calcWarnLevel(rectificationInfo1, deadlineNodeList, finalDeadlinePeriods);
//                // 检查警告级别是否变化
//
//                Integer newLevel = updatedInfo.getWarnLevel();
//                if (!Objects.equals(oldLevel, newLevel)) {
//                    ChangeWarnLevel changeWarnLevel = new ChangeWarnLevel();
//                    changeWarnLevel.setRectificationId(rectificationInfo1.getId());
//                    changeWarnLevel.setOldWarnLevel(oldLevel);
//                    changeWarnLevel.setNewWarnLevel(newLevel);
//                    changeWarnLevel.setCurrentNode(updatedInfo.getCurrentNode());
//                    changeWarnLevel.setCreatTime(new Date()); // 注意：属性名可能存在拼写错误(createTime)
//                    changeWarnLevels.add(changeWarnLevel);
//                }
//
//                // 更新原始对象
//                rectificationInfo1.setWarnLevel(newLevel);
//                rectificationInfo1.setCurrentNode(updatedInfo.getCurrentNode());
//                processedList.add(rectificationInfo1);
//            }
//            rectificationInfoList = processedList;
//        }
//        for (RectificationInfo rectificationInfo:rectificationInfoList){
//            rectificationInfoMapper.updateById(rectificationInfo);
//        }
//        for (ChangeWarnLevel changeWarnLevel:changeWarnLevels){
//            changeWarnLevelMapper.insert(changeWarnLevel);
//        }
    }


    private List<RectificationInfo> fetchAllRectification(String currentDepartment) {
        // 1. 并行执行三个数据查询
        ExecutorService executor = Executors.newFixedThreadPool(3);

        Future<List<RectificationInfo>> rectificationFuture = executor.submit(() -> {
            LambdaQueryWrapper<RectificationInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.ne(RectificationInfo::getState, "已关闭")
                    .ne(RectificationInfo::getState, "已销号")
                    .ne(RectificationInfo::getState, "已退出")
                    .orderByAsc(RectificationInfo::getId);
            return rectificationInfoMapper.selectList(wrapper);
        });
        // 2. 获取结果
        List<RectificationInfo> rectificationList = new ArrayList<>();

        try {
            rectificationList = rectificationFuture.get();
        } catch (InterruptedException | ExecutionException e) {
            // 处理异常，记录日志等
            Thread.currentThread().interrupt();
        } finally {
            executor.shutdown();
        }
        return rectificationList;
    }


    /**
     * 过滤节点
     */
    private List<DeadlineNode> filiterNode(RectificationInfo rectificationInfo, List<DeadlineNode> deadlineNodeList) {
        // 排除 progress 为 / 的节点
        return deadlineNodeList.stream()
                .filter(node -> node.getProgress() == null || !"/".equals(node.getProgress()))
                .collect(Collectors.toList());
    }


    private RectificationInfo calcWarnLevel(RectificationInfo rectificationInfo,List<DeadlineNode> deadlineNodeList,List<DeadlineRectificationPeriod> deadlineRectificationPeriods){
        // === 你现有 currentNode 计算（不变）===
        if (rectificationInfo.getIsNotCalc()){
            return rectificationInfo;
        }
        Map<Integer, List<DeadlineRectificationPeriod>> deadlineRectificationPeriodMap = new HashMap<>();
        if (deadlineRectificationPeriods!=null) {
            deadlineRectificationPeriodMap = deadlineRectificationPeriods.stream().filter(o->o.getDeadlineNodeId()!=null).collect(Collectors.groupingBy(DeadlineRectificationPeriod::getDeadlineNodeId));
        }
        List<DeadlineNode> qualifiedNodes = new ArrayList<>();
        List<DeadlineNode> qualifiedNodesT = new ArrayList<>();
        Date today = new Date();
        String currentNode = "";
        // 第一步：筛选符合条件的节点
        StringBuilder sb = new StringBuilder();
        for (DeadlineNode d : deadlineNodeList) {
            if (deadlineRectificationPeriodMap != null) {
                List<DeadlineRectificationPeriod> deadlineRectificationPeriodList = deadlineRectificationPeriodMap.get(d.getId());

                if (deadlineRectificationPeriodList != null) {
                    // 排序并过滤后的列表
                    List<DeadlineRectificationPeriod> sortedList = deadlineRectificationPeriodList.stream()
                            .filter(item -> item.getRectificationTime() != null)
                            .sorted(Comparator.comparing(DeadlineRectificationPeriod::getRectificationTime,
                                    Comparator.reverseOrder()))
                            .collect(Collectors.toList());

                    // 先判断列表是否有元素，再获取第一个
                    if (!sortedList.isEmpty()) {
                        d.setDeadlineRectificationPeriod(sortedList.get(0).getRectificationTime());
                    }
                }
            }
            // 1. 必须有截止日期
            if (d.getDeadlineRectificationPeriod() == null) {
                d.setDeadlineRectificationPeriod(d.getDeadline());
            }
            if (d.getDeadlineRectificationPeriod() == null) {
                continue;
            }else {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(d.getDeadlineRectificationPeriod());
                calendar.set(Calendar.HOUR_OF_DAY, 23);
                calendar.set(Calendar.MINUTE, 59);
                calendar.set(Calendar.SECOND, 59);
                d.setDeadlineRectificationPeriod(calendar.getTime());
            }
            Date endTime = d.getEndTime();
            if (endTime == null && d.getDeadlineRectificationPeriod().before(today)) {
                qualifiedNodesT.add(d);

            } else {
                if (d.getDeadlineRectificationPeriod().after(today)&&endTime != null) {
                    qualifiedNodes.add(d);
                }
            }

        }
        if (!qualifiedNodesT.isEmpty()) {
            for (DeadlineNode node : qualifiedNodesT) {
                if (null!=node && StringUtils.isNotBlank(node.getName()) && node.getEndTime() == null) {
                    if (node.getName().contains("节点") &&
                            node.getName().length() == 3 &&
                            node.getMainId()>100000 &&
                            StrUtil.isNotBlank(node.getDepartmentName())){
                        node.setName(node.getDepartmentName()+"-"+node.getName());
                    }
                    sb.append(node.getName()).append("; "); // 用分号分隔多个节点
                }
            }
        }else if (!qualifiedNodes.isEmpty()){
            //             第二步：从符合条件的节点中，筛选出最早截止日期的节点
            // 找到最早的截止日期
            Date earliestDeadline = qualifiedNodes.get(0).getDeadlineRectificationPeriod();
            for (DeadlineNode node : qualifiedNodes) {
                if (node.getDeadlineRectificationPeriod().before(earliestDeadline)) {
                    earliestDeadline = node.getDeadlineRectificationPeriod();
                }
            }

            // 拼接所有最早截止日期的节点名称
            for (DeadlineNode node : qualifiedNodes) {
                if (node.getDeadlineRectificationPeriod().equals(earliestDeadline) && node.getEndTime() == null) {
                    if (node.getName().contains("节点") &&
                            node.getName().length() == 3 &&
                            node.getMainId()>100000 &&
                            StrUtil.isNotBlank(node.getDepartmentName())){
                        node.setName(node.getDepartmentName()+"-"+node.getName());
                    }
                    sb.append(node.getName()).append("; "); // 用分号分隔多个节点
                }
            }
        }
        // 移除最后一个分隔符
        if (sb.length() > 0) {
            currentNode = sb.substring(0, sb.length() - 2);
        }

        if (StrUtil.isEmptyIfStr(currentNode)) {
            for (DeadlineNode d : deadlineNodeList) {
                if (d.getDeadlineRectificationPeriod() != null) {
                    if (d.getDeadlineRectificationPeriod().after(new Date()) && d.getEndTime() == null) {
                        currentNode = d.getName();
                    }
                }
            }
        }
        rectificationInfo.setCurrentNode(currentNode);
        // === 你现有 warnLevel（按“当前环节”）计算（不变）===
        Integer warnLevel = 0;
        for (DeadlineNode node : deadlineNodeList) {
            boolean isCurrentNode = false;
            if (currentNode.contains(node.getName())) {
                isCurrentNode = true;
                int nodeWarnLevel = Convert.toInt(node.getWarnLevel(), 0);
                if (nodeWarnLevel == 2) {
                    warnLevel = 2;
                    break;
                } else if (warnLevel < 1 && nodeWarnLevel == 1) {
                    warnLevel = 1;
                }
            }
            if (isCurrentNode) {
                int nodeWarnLevel = Convert.toInt(node.getWarnLevel(), 0);
                if (nodeWarnLevel == 2) {
                    warnLevel = 2;
                    break;
                } else if (warnLevel < 1 && nodeWarnLevel == 1) {
                    warnLevel = 1;
                }
            }
        }
        rectificationInfo.setWarnLevel(warnLevel);
        return rectificationInfo;
    }




}
